package tester.utilities;

import sun.reflect.*;

import java.lang.reflect.*;

/**
 * This class can be used to set field values regardless 
 * of the modifiers.
 * @author Weston Jossey
 * @since Feb 1 2009
 */
public class ReflectionHelper {

	private static final String MODIFIERS_FIELD = "modifiers";

	private static final ReflectionFactory reflection = ReflectionFactory
			.getReflectionFactory();

	/**
	 * Set the value of the field of the object to the given value.
	 * @param original object to modify
	 * @param field field to modify
	 * @param value new value for the given object and field
	 * @throws NoSuchFieldException
	 * @throws IllegalAccessException
	 */
	public static void setStaticFinalField(Object original, Field field,
			Object value) throws NoSuchFieldException,
			IllegalAccessException {
		// we mark the field to be public
		field.setAccessible(true);
		// next we change the modifier in the Field instance to
		// not be final anymore, thus tricking reflection into
		// letting us modify the static final field
		Field modifiersField = Field.class
				.getDeclaredField(MODIFIERS_FIELD);
		modifiersField.setAccessible(true);
		int modifiers = modifiersField.getInt(field);
		// blank out the final bit in the modifiers int
		modifiers &= ~Modifier.FINAL;
		modifiersField.setInt(field, modifiers);
		FieldAccessor fa = reflection.newFieldAccessor(field, false);
		fa.set(original, value);
	}
}
